package com.coldchain.common.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.coldchain.common.msg.ObjectRestResponse;
import com.coldchain.common.vo.AddressComponentVo;
import com.coldchain.common.vo.PathsVo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * 函数类
 */
public class FunctionUtils{

	/*	地图定位城市
		https://lbs.amap.com/api/webservice/guide/api/georegeo
		路线规划
		https://lbs.amap.com/api/webservice/guide/api/direction
	 */
	/**
	 * 高德地图key
	 */
	private static final String GAO_KEY="54e2a7d7cc11d9798ff0e8c59dd3336a";
	/**
	 * 为地球半径，单位为千米
	 */
	private static double EARTH_RADIUS = 6378.137;

	/**
	 * 逆地理编码
	 * @param location 经纬度坐标;最多支持20个坐标点;多个点之间用"|"分割。
	 * @param batch batch=true为批量查询。batch=false为单点查询
	 * @return
	 */
	public static final List<AddressComponentVo> regeo(String location, boolean batch){
		//		output=xml&location=116.310003,39.991957
		//			&key=<用户的key>&radius=1000&extensions=all 
		List<AddressComponentVo> list =new ArrayList<>();
		String url = "https://restapi.amap.com/v3/geocode/regeo";
		String param = "?key="+GAO_KEY+"&location="+location+"&batch="+batch;
		
		String response = cn.hutool.http.HttpUtil.get(url + param) ;
		//String response = HttpUtil.postServer(url, param); 
		JSONObject jsonObj = JSONObject.parseObject(response);
		if(batch){//批量
			JSONArray regeocodes = jsonObj.getJSONArray("regeocode");
			for(int x =0;x< regeocodes.size();x++){
				JSONObject job = regeocodes.getJSONObject(x);
				JSONObject addressComponent = job.getJSONObject("addressComponent");
				AddressComponentVo vo = new AddressComponentVo();
				vo.setAdcode(addressComponent.getInteger("adcode"));
				vo.setDistrict(addressComponent.getString("district"));
				vo.setProvince(addressComponent.getString("province"));
				vo.setTownship(addressComponent.getString("township"));
				vo.setTowncode(addressComponent.getString("towncode"));
				vo.setCitycode(addressComponent.getString("citycode"));
				list.add(vo);
			}
		}else{//不是批量
			JSONObject regeocode = jsonObj.getJSONObject("regeocode");
			if(regeocode!=null){
				JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
				if(addressComponent!=null){
					AddressComponentVo vo = new AddressComponentVo();
					vo.setAdcode(addressComponent.getInteger("adcode"));
					vo.setDistrict(addressComponent.getString("district"));
					vo.setProvince(addressComponent.getString("province"));
					vo.setTownship(addressComponent.getString("township"));
					vo.setTowncode(addressComponent.getString("towncode"));
					vo.setCitycode(addressComponent.getString("citycode"));
					list.add(vo);
				}
			}
		}
		return list;
	}

	/**
	 * 驾车路径规划
	 * @param origin lon,lat 开始（经度,纬度）
	 * @param destination lon,lat 结束（经度,纬度）
	 * @param strategy 推荐 19优先选择高速
	 * @param waypoints 途径点;分开
	 * @return 返回最短距离路线
	 */
	public static final PathsVo driving(String origin, String destination, Integer strategy, String waypoints){
		String url="https://restapi.amap.com/v3/direction/driving";
		String param = "?key="+GAO_KEY+"&origin="+origin+"&destination="
				+destination+"&strategy="+strategy+"&extensions=base&ferry=1"+"&waypoints="+waypoints;
		String response = cn.hutool.http.HttpUtil.get(url + param);
		JSONObject jsonObj = JSONObject.parseObject(response);
		PathsVo vo = null;
		if(jsonObj!=null){
			JSONObject route = jsonObj.getJSONObject("route");
			if(route!=null){
				JSONArray paths = route.getJSONArray("paths");
				for(int x = 0 ;x < paths.size();x++){
					JSONObject job = paths.getJSONObject(x);
					if(job!=null){
						if(vo==null){
							vo = new PathsVo();
							vo.setDistance(Double.valueOf(job.getString("distance")));
							vo.setDuration(Double.valueOf(job.getString("duration")));
							vo.setTolls(Double.valueOf(job.getString("tolls")));
						}else{
							if(vo.getDistance()>Double.valueOf(job.getString("distance"))){
								vo.setDistance(Double.valueOf(job.getString("distance")));
								vo.setDuration(Double.valueOf(job.getString("duration")));
								vo.setTolls(Double.valueOf(job.getString("tolls")));
							}
						}
					}
				}
			}
		}
		return vo;
	}

	@SuppressWarnings("rawtypes")
	public static ObjectRestResponse getSuccessRest(String message){
		ObjectRestResponse response = new ObjectRestResponse();
		response.setMessage(message);
		return response;
	}
	
	@SuppressWarnings("rawtypes")
	public static ObjectRestResponse getFailRest(String message){
		ObjectRestResponse response = new ObjectRestResponse();
		response.error(message);
		return response;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static ObjectRestResponse getSuccessRest(String message,Object data){
		ObjectRestResponse response = new ObjectRestResponse(data);
		response.setMessage(message);
		response.setData(data);
		return response;
	} 
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static ObjectRestResponse getFailRest(String message,Object data){
		ObjectRestResponse response = new ObjectRestResponse(data);
		response.error(message);
		response.setData(data);
		return response;
	} 
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static ObjectRestResponse getSuccessRest(String message, int status, Object data){
		ObjectRestResponse response = new ObjectRestResponse(data);
		response.setMessage(message);
		response.setStatus(status);
		response.setData(data);
		return response;
	}
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static ObjectRestResponse getFailRest(String message,int status,Object data){
		ObjectRestResponse response = new ObjectRestResponse(data);
		response.error(message);
		response.setStatus(status);
		response.setData(data);
		return response;
	} 
	/**
	 * 获取单号
	 * @param a 1承运商 2货主 3订单 4司机 5平台
	 * @param b 1提现 2订单
	 * @return
	 */
	public static final String getOrderCode(String a, String b) {
		String time;
		java.util.Calendar cal = new java.util.GregorianCalendar();
		int random = (int) (Math.random() * 900) + 100;
		time = "" + a + b + cal.get(Calendar.HOUR) + String.valueOf(random).charAt(0) + cal.get(Calendar.MINUTE) + String.valueOf(random).charAt(1) + cal.get(Calendar.SECOND)
		+ String.valueOf(random).charAt(2) + cal.get(Calendar.MILLISECOND);
		return time;
	}
	
	/**
	 * 获取单号
	 * @param a 1承运商 2货主 3订单 4司机 5平台
	 * @param b 1提现 2订单
	 * @return
	 */
	public static final String getOrderCode(Integer a,Integer b) {
		String time;
		java.util.Calendar cal = new java.util.GregorianCalendar();
		int random = (int) (Math.random() * 900) + 100;
		time = "" + a + b + cal.get(Calendar.HOUR) + String.valueOf(random).charAt(0) + cal.get(Calendar.MINUTE) + String.valueOf(random).charAt(1) + cal.get(Calendar.SECOND)
		+ String.valueOf(random).charAt(2) + cal.get(Calendar.MILLISECOND);
		return time;
	}


	/**
	 * 计算两组 经纬度 相隔对少米
	 * @param lat1 A 纬度
	 * @param lng1 A 经度
	 * @param lat2 B 纬度
	 * @param lng2 B 经度
	 * @return  返回千米
	 */
	public static double getDistance(double lat1, double lng1, double lat2, double lng2){
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) + 
				Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));
		s = s * EARTH_RADIUS;
		DecimalFormat df = new DecimalFormat("######0.00");   
		double f=Double.parseDouble(df.format(s));
		return f;
	}

	private static double rad(double d){
		return d * Math.PI / 180.0;
	}


	/**************************加减乘除************************************/

	/**
	 * 加
	 * @param a1  加数
	 * @param a2 被加数
	 * @param index 保留位数
	 * @return 四舍五入 保留两位小数
	 */
	public static BigDecimal add(BigDecimal a1, BigDecimal a2, int index) {
		return a1.add(a2).setScale(index, BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 减
	 * @param a1 减数
	 * @param a2 被减数
	 * @param index 保留位数
	 * @return 四舍五入 保留两位小数
	 */
	public static BigDecimal sub(BigDecimal a1, BigDecimal a2, int index) {
		return a1.subtract(a2).setScale(index, BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 乘
	 * @param a1 乘数
	 * @param a2 被乘数
	 * @param index 保留位数
	 * @return 四舍五入 保留两位小数
	 */
	public static BigDecimal mul(BigDecimal a1, BigDecimal a2, int index) {
		return a1.multiply(a2).setScale(index, BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 除
	 * 
	 * @param d1 除数
	 * @param d2 被除数
	 * @param index 保留位数
	 * @return 四舍五入 保留两位小数
	 */
	public static BigDecimal div(BigDecimal d1, BigDecimal d2, int index) {
		return d1.divide(d2, index, BigDecimal.ROUND_HALF_UP);
	}

	/**
	 * 获取真实ip
	 * @param request
	 * @return
	 */
	public static String getRemoteHost(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	public static void getWriter(HttpServletResponse response, String msg) {
		try {
			response.getWriter().write(msg);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	
	
}
